﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Kotonoha.Server.Dictionaries;

namespace Kotonoha.Server.Examples {
    public class Examples {
        private readonly ExamplesIndex index;
        private readonly Stream file;
        private readonly Encoding encoding;
        private readonly Random random = new Random((int) DateTime.Now.Ticks);

        public Examples(ExamplesIndex index, Stream file, Encoding encoding) {
            this.index = index;
            this.encoding = encoding;
            this.file = file;
        }

        public List<ExampleEntry> findExamples(string word, int recommended) {
            List<ExampleEntry> examples = new List<ExampleEntry>();
            IndexEntry entry = index[word];
            int meanings = entry.MeaningLength;
            int maxPerMeaning = (int) Math.Ceiling(recommended/(float) meanings);
            foreach(KeyValuePair<int, Meaning> pair in entry) {
                Meaning m = pair.Value;
                List<long> positions = new List<long> {m[0].Position};
                for(int i = 1; i < maxPerMeaning && i < m.CountCases;) {
                    long position = m[random.Next(1, m.CountCases)].Position;
                    if (positions.IndexOf(position) == -1) {
                        positions.Add(position);
                        ++i;
                    }
                }
                string[] results = ExampleFinder.findAStringsByPositions(file, encoding, positions.ToArray());
                foreach(string aString in results) {
                    examples.Add(createExample(aString));
                }
            }
            return examples;
        }

        //A: 「４ポンド５０ペンス」とボブが言う。	"Four pounds fifty" says Bob.#ID=10
        public static ExampleEntry createExample(string s) {
            const int start = 3;
            int exEnd = s.IndexOf('	');
            int trStart = exEnd + 1;
            int trEnd = s.IndexOf('#');

            return new ExampleEntry
                       {Content = s.Substring(start, exEnd - start),
                       Translation = s.Substring(trStart, trEnd - trStart)};
        }
    }

    public class ExampleEntry {
        public virtual long Id { get; set;}
        public virtual string Content { get; set; }
        public virtual string Translation { get; set; }
    }
 
    public class ExampleInfo {
        public virtual ExampleEntry Example { get; set; }
        public virtual WordEntry Word { get; set; }
        public virtual int Number { get; set; }
        public virtual int Recommended { get; set; }

        public virtual bool Equals(ExampleInfo other) {
            if (ReferenceEquals(null, other)) {
                return false;
            }
            if (ReferenceEquals(this, other)) {
                return true;
            }
            return Equals(other.Example, Example) && Equals(other.Word, Word);
        }

        public override bool Equals(object obj) {
            if (ReferenceEquals(null, obj)) {
                return false;
            }
            if (ReferenceEquals(this, obj)) {
                return true;
            }
            if (obj.GetType() != typeof (ExampleInfo)) {
                return false;
            }
            return Equals((ExampleInfo) obj);
        }

        public override int GetHashCode() {
            unchecked {
                return (Example.GetHashCode()*397) ^ Word.GetHashCode();
            }
        }
    }
}
